<template>
  <!-- 下拉搜索框 -->
  <el-select
    ref="customSelect"
    v-model="curSel"
    style="width:100%"
    filterable
    :clearable="clearable"
    :remote="remote"
    :disabled="disabled||sspDisabled"
    :multiple="multiple"
    reserve-keyword
    :remote-method="remoteMethod"
    :loading="loading"
    value-key="id"
    v-bind="$attrs"
    @visible-change="isShowSelectOptions"
    @change="selectChange"
    @focus="onFocus()"
    @clear="handlerClear"
    @blur="onBlur()"
  >
    <slot></slot>
    <el-option
      v-for="(item, index) in list"
      :key="`${item.id}${index}`"
      :label="labelSet(item)"
      :value="item[valueName]"
    ></el-option>
  </el-select>
</template>
<script>
import request from '@/utils/request'
const staffInfo = '/call-center/api/v1/staffInfo/page'
export default {
  name: 'SearchSelectPicker',
  inheritAttrs: false,
  props: {
    remote: {
      type: Boolean,
      default: true
    },
    value: {
      // 选中的值
      type: [Number, String, Array],
      default: ''
    },
    lable: {
      // 选中值的名称
      type: [String, Array],
      default: ''
    },
    currentId: {
      type: String,
      default: ''
    },
    curOptions: {
      // 选中的option
      type: [Array, Object],
      default: () => {
        return {}
      }
    },
    valueName: {
      // 选项值键名
      type: String,
      default: 'id'
    },
    lableName: {
      // 选项名称键名
      type: String,
      default: ''
    },
    customName: {
      // 输入值的查询键名，有值时使用，否则使用lableName
      type: String,
      default: ''
    },
    url: {
      // 分页查询地址
      type: String,
      default: staffInfo
    },
    parentId: {
      // 父级id
      type: [String, Number, Array],
      default: ''
    },
    mustPid: {
      // 是否必须有父级id
      type: Boolean,
      default: false
    },
    clearable: {
      type: Boolean,
      default: true
    },
    multiple: {
      // 多选时value，lable必须为数组
      type: Boolean,
      default: false
    },
    method: {
      // 请求方式,默认post
      type: String,
      default: 'post'
    },
    params: {
      // 请求参数,query参数，type方式（msc post分页区分 1）
      type: Object,
      default: () => {
        return { query: null, type: 0 }
      }
    },
    otherRaw: {
      type: Object,
      default: () => ({})
    },
    mustVal: {
      // 是否必须有值查询
      type: Boolean,
      default: false
    },
    labelFunc: {
      type: Function,
      default: null
    },
    disabled: {
      type: Boolean,
      default: false
    },
    sspDisabled: {
      type: Boolean,
      default: false
    },
    platformNo: {
      type: [String, Array],
      default: ''
    },
    selectData: {
      type: Array,
      default: undefined
    },
    pageSize: {
      type: Number,
      default: 50
    }
  },
  data() {
    return {
      loading: false,
      curSel: '',
      tempLable: null, // 选中项的name值，没有绑定lable时使用
      list: []
    }
  },
  watch: {
    value: {
      handler(val) {
        if (this.multiple) {
          this.curSel = val.map(e => {
            return e.toString()
          })
        } else {
          this.curSel = (val || '').toString()
          if (!val) {
            this.tempLable = null
          }
          // this.remoteMethod()
        }
        // 数据请求未返回时，设置默认选项
        this.setList(this.curSel)
      },
      deep: true,
      immediate: true
    },
    url: {
      handler() {
        this.remoteMethod()
      },
      immediate: true
    },
    parentId: {
      // 监听parentId实现父级变化后刷新列表
      handler(val) {
        this.remoteMethod()
      }
    }
    // params: {
    //   handler() {
    //     this.remoteMethod()
    //   },
    //   deep: true
    // }
  },
  methods: {
    // 是否显示下拉框
    isShowSelectOptions(bol) {
      const thisNode = this.$refs.customSelect
      try {
        if (!bol) thisNode.blur()
        // 使远程搜索框可以选择
        if (bol && !this.multiple) {
          thisNode.selectedLabel = this.tempLable ? this.tempLable : this.lable
        }
      } catch (error) {
        console.log(error)
      }
    },
    // 选择变化
    selectChange(val) {
      if (this.multiple) {
        const nameList = []
        const ary = []
        const platformNoList = []
        val.forEach(code => {
          const item = this.list.find(e => {
            return e[this.valueName] === code
          })
          nameList.push(item[this.lableName])
          ary.push(item)
          if (this.platformNo) {
            platformNoList.push(item.platformNo)
          }
        })
        this.$emit('update:curOptions', ary)
        this.$emit('update:lable', nameList)
        this.$emit('update:platformNo', platformNoList)
        this.$emit('selectChange', ary)
      } else {
        const obj = this.list.find(e => {
          return e[this.valueName] === val
        })
        const name = obj ? obj[this.lableName] : ''
        this.tempLable = name
        this.$emit('update:lable', name)
        this.$emit('update:platformNo', obj ? obj.platformNo : '')
        this.$emit('update:curOptions', obj)
        this.$emit('update:currentId', obj ? obj.id : '')
        this.$emit('selectChange', obj)
      }
      this.$emit('update:value', val)
    },
    setList(val) {
      // 判断列表中是否有传入的选项
      if (this.multiple) {
        for (const i in val) {
          const bol = this.list.every(e => {
            return e[this.valueName] !== val[i]
          })
          // 没有当前选项则加上
          if (bol) {
            if (this.lable) {
              const d = {
                [this.lableName]: this.lable[i],
                [this.valueName]: val[i]
              }
              if (this.platformNo) {
                d.platformNo = this.platformNo || ''
              }
              this.list.unshift(d)
            } else {
              const d = {
                [this.lableName]: this.tempLable[i],
                [this.valueName]: val[i]
              }
              if (this.platformNo) {
                d.platformNo = this.platformNo || ''
              }
              this.list.unshift(d)
            }
          }
        }
      } else {
        const bol = this.list.every(e => {
          return e[this.valueName] !== val
        })
        // 没有当前选项则加上
        if (bol && this.value) {
          const d = {
            [this.lableName]: this.lable ? this.lable : this.tempLable,
            [this.valueName]: val
          }
          if (this.platformNo) {
            d.platformNo = this.platformNo || ''
          }
          this.list.unshift(d)
        }
      }
    },
    remoteMethod(val) {
      if (this.selectData) {
        this.list = this.selectData
        this.setList(this.curSel)
        return
      }
      if (this.mustPid && !this.parentId) {
        this.list = []
        this.setList(this.curSel)
        return
      }
      if (this.mustVal && !val) {
        return
      }
      const formObj = new FormData()
      const filtersRaw = []
      const obj = { ...this.params.query }
      if (val) delete obj[this.customName]
      if (obj) {
        for (const i in obj) {
          if (Array.isArray(obj[i]) && obj[i].length === 2 && isNaN(Number(obj[i][0]))) {
            filtersRaw.push({
              id: Math.floor(Math.random() * 0xffffffffff).toString(16),
              value: obj[i][0],
              property: i,
              operator: '>='
            })
            filtersRaw.push({
              id: Math.floor(Math.random() * 0xffffffffff).toString(16),
              value: obj[i][1],
              property: i,
              operator: '<='
            })
          } else if (obj.hasOwnProperty(i) && Object.prototype.toString.call(obj[i]) === '[object Object]') {
            const v = obj[i]
            if (v.value === '' || v.value === undefined || v.value === null) {
              continue
            }
            if (v.value instanceof Array) {
              if (v.value.length <= 0) {
                continue
              } else {
                v.value = `[${v.value.join(',')}]`
              }
            }
            filtersRaw.push({
              id: Math.floor(Math.random() * 0xffffffffff).toString(16),
              value: v.value,
              property: i,
              operator: v.operator
            })
          } else if (obj.hasOwnProperty(i) && Object.prototype.toString.call(obj[i]) === '[object Array]' && obj[i] !== '[]') {
            // const v = obj[i]
            if (obj[i] instanceof Array) {
              if (obj[i].length <= 0) {
                continue
              } else {
                obj[i] = `[${obj[i].join(',')}]`
              }
            }
            filtersRaw.push({
              id: Math.floor(Math.random() * 0xffffffffff).toString(16),
              value: obj[i],
              property: i,
              operator: 'in'
            })
          } else if (obj[i] !== '[]' && obj[i] !== '' && obj[i] !== undefined && obj[i] !== null) {
            filtersRaw.push({
              id: Math.floor(Math.random() * 0xffffffffff).toString(16),
              value: obj[i],
              property: i,
              operator: 'like'
            })
          }
        }
      }
      if (val) {
        if (this.valueName === 'accountNo' || this.valueName === 'account') {
          if (/^[a-zA-Z]/.test(val)) {
            filtersRaw.push({
              id: Math.floor(Math.random() * 0xffffffffff).toString(16),
              value: val,
              property: this.valueName,
              operator: 'like'
            })
          } else {
            filtersRaw.push({
              id: Math.floor(Math.random() * 0xffffffffff).toString(16),
              value: val,
              property: this.lableName,
              operator: 'like'
            })
          }
        } else {
          filtersRaw.push({
            id: Math.floor(Math.random() * 0xffffffffff).toString(16),
            value: val,
            property: this.customName ? this.customName : this.lableName,
            operator: 'like'
          })
        }
      }
      const otherRaw = {}
      for (const [k, v] of Object.entries(this.otherRaw)) {
        if (v === '' || v === null || v === undefined) {
          continue
        }
        if (v instanceof Array) {
          const _v = v.filter(e => e !== '' && e !== null && e !== undefined)
          if (_v.length > 0) {
            otherRaw[k] = `[${_v.join(',')}]`
          }
        } else if (Object.prototype.toString.call(v) === '[object Object]') {
          otherRaw[k] = JSON.stringify(v)
        }
      }
      formObj.append('page', 1)
      formObj.append('rows', this.pageSize)
      formObj.append('filtersRaw', JSON.stringify(filtersRaw))
      formObj.append('paramsRaw', JSON.stringify(otherRaw))
      // 电商平台，店铺接口数据处理
      // const obj = this.params.query
      const strList = ['page=1', `rows=${this.pageSize}`]
      let str = ''
      for (const i in obj) {
        if (obj[i]) {
          strList.push(i + '=' + obj[i])
        }
      }
      if (val) {
        strList.push(
          (this.customName ? this.customName : this.lableName) + '=' + val
        )
      }
      if (strList.length) {
        str = '?' + strList.join('&')
      }
      if (this.method === 'get') {
        this.loading = true
        request({
          url: this.url + str,
          method: this.method
        })
          .then(res => {
            this.loading = false
            if (res.success === 1) {
              if (Object.keys(res.data).indexOf('records') === -1) {
                this.list = res.data.map(e => {
                  e[this.valueName] = e[this.valueName].toString()
                  return e
                })
              } else {
                this.list = res.data.records.map(e => {
                  e[this.valueName] = e[this.valueName].toString()
                  return e
                })
              }
              this.setList(this.curSel)
            }
          })
          .catch(er => {
            this.loading = false
          })
      } else {
        this.loading = true
        request({
          url: this.url + (this.params.type === 1 ? str : ''),
          method: this.method,
          data: this.params.type === 0 ? formObj : ''
        })
          .then(res => {
            this.loading = false
            if (res.success === 1) {
              if (Object.keys(res.data).indexOf('records') === -1) {
                this.list = res.data.map(e => {
                  e[this.valueName] = e[this.valueName].toString()
                  return e
                })
              } else {
                this.list = res.data.records.map(e => {
                  e[this.valueName] = e[this.valueName].toString()
                  return e
                })
              }
              this.setList(this.curSel)
            }
          })
          .catch(er => {
            this.loading = false
          })
      }
    },
    onFocus() {
      // 获取焦点刷新，建议删除（刷新数据太频繁，每次选择要等待数据刷新）
      if (!this.multiple) this.remoteMethod()
      if (this.$listeners['on-focus'] instanceof Function) {
        this.$listeners['on-focus']()
      }
    },
    onBlur() {
      if (this.$listeners['on-blur'] instanceof Function) {
        this.$listeners['on-blur']()
      }
    },
    labelSet(item) {
      if (this.labelFunc) {
        return this.labelFunc(item)
      } else if ('platformNo' in item && 'accountNo' in item) {
        return `${item[this.lableName]}(${item.accountNo}) - ${item.platformNo}`
      } else {
        return item.accountNo ? (item[this.lableName] + '(' + item.accountNo + ')') : item.account ? (item[this.lableName] + '(' + item.account + ')') : item[this.lableName]
      }
    },
    handlerClear() {
      this.$nextTick(() => {
        this.remoteMethod('')
      })
    }
  }
}
</script>
<style lang="scss" scoped>
</style>
